#pragma once
#include <string>
#include "refc_ptr.h"
#include "md5_mesh_parser.h"
#include "vector3.h"
#include "mesh.h"
#include "model.h"
#include "material.h"
#include "matrix.h"

namespace krryn{
namespace animation{ class skeleton; class animation; }
namespace view{ class renderer; class model; }
namespace data{
	class md5_anim_parser;

	class md5_mesh_builder{
	public:
		md5_mesh_builder(const std::string &a_Directory);
		~md5_mesh_builder();
		view::model* build_model(view::renderer &a_Renderer);
	private:
		krryn::math::matrix m_CoordinateCorrection;

		md5_mesh_parser m_Parser;
		std::vector<md5_anim_parser *> m_AnimationParsers;

		std::string make_mesh_filename(const std::string &a_Path);
		core::refc_ptr<view::material> build_material(view::renderer &a_Renderer, md5_mesh &a_Mesh);
		core::refc_ptr<view::index_buffer> build_index_buffer(view::renderer &a_Renderer, md5_mesh &a_Mesh);
		core::refc_ptr<view::vertex_buffer> build_vertex_buffer(view::renderer &a_Renderer, md5_mesh &a_Mesh, md5_joint *a_Skeleton);
		animation::skeleton *build_skeleton(int a_NumJoints, md5_joint *a_Joints);
		animation::animation *build_animation(view::model *a_Model, int a_FrameRate, int a_NumFrames, int a_NumJoints, md5_joint **a_Joints);
		void compute_bind_pose_positions(md5_mesh &a_Mesh, md5_joint *a_Skeleton, std::vector<math::vector3f> &a_BindPosePositions);
		void compute_bind_pose_normals(md5_mesh &a_Mesh, std::vector<math::vector3f> &a_BindPosePositions, std::vector<math::vector3f> &a_BindPoseNormals);
		math::vector3f compute_triangle_normal(math::vector3f a_P1, math::vector3f a_P2, math::vector3f a_P3);
	};
}
}